Move 的兩個核心元素 script
, module
。
function 執行進入點,主要目的是調用已發布的 module 的 function,這些 function 執行全局存儲模式的更新。
script {
// 使用聲明來 import (後面會介紹)
<use>*
// 任何常量
<constants>*
// main function
// 任何數量參數,不能有返回值
fun <identifier><[type parameters: constraint]*>([identifier: type]*) <function_body>
}
script {
// 導入 Debug Module
use Std::Debug;
const ONE: u64 = 1;
fun main(x: u64) {
let sum = x + ONE;
Debug::print(&sum)
}
}
定義 struct type 以及對這些 type 進行操作的 function 的位置。struct type 定義了 Move 的全局存儲模式 (之後會提到),模塊函數定義了更新存儲的規則。模塊本身也存儲在全局存儲中。
一個 Move source file 可能包含多個 module and script。
注意: Module 中不能使用 let
module <address>::<identifier> {
(<use> | <friend> | <type> | <function> | <constant>)*
}
該module 0x42::Test
指定名為 Test
的 Module 將在全局存儲中的帳戶地址(0x42
) 下發布。
module 0x42::Test {
struct Example has copy, drop { i: u64 }
use Std::Debug; // 使用來自其他 Module 的導入類型
friend 0x42::AnotherTest; // 指定受信任的 Module 列表
const ONE: u64 = 1; // 指定常量,可以在 Module 內使用的私有常量
public fun print(x: u64) {
...
}
}
camel case
範例: FixedPoint, Vectorcamel case
範例: Coin, RoleIdlower snake case
範例: destroy_emptyupper snake case
範例: REQUIRES_CAPABILITYlower snake case
並與 Script 裡的 main function 名字一樣lower snake case
,且名稱和內部任何特定 Module / Script 都不匹配as
重新命名// Module
module 0x1::Foo {
struct Foo { }
const CONST_FOO: u64 = 0;
public fun do_foo(): Foo { Foo{} }
...
}
// 導入並使用
module 0x1::Bar {
use 0x1::Foo::{Self, Foo}; // use 宣告在 module 頂部
public fun do_bar(x: u64): Foo {
if (x == 10) {
Foo::do_foo() // function 個別導入,不要在最上面就導入
} else {
abort 0
}
}
...
}
// 名字衝突
module OtherFoo {
struct Foo {}
...
}
module 0x1::Importer {
use 0x1::OtherFoo::Foo as OtherFoo; // 使用 as
use 0x1::Foo::Foo;
....
}
每個 Module Struct, Public function 都應該註釋。
///
//
/* */
筆者認為,編碼約定主要是清楚得讓自己和其他人可以更好的閱讀程式碼,無論是本章介紹的 Move 團隊或其他格式指南和約定,都沒有限定。
本章介紹了 Module 兩大核心元素和命名規則,有些內容在之後幾天會介紹到,歷時再回頭看本篇或許會更理解,讓我們 Move to Day3。